/*
 * Copyright (c) 2010, 2012 Luan Nguyen Thanh. All rights reserved.
 * 
 * This code is written by Luan Nguyen Thanh, with any partners involved.
 * The unauthorized use of this code should not be permitted!
 */
package MyIM.client.view;

import MyIM.client.Client;
import MyIM.client.engine.Engine;
import MyIM.client.view.component.FriendListItem;
import MyIM.client.view.component.FriendsPopupMenu;
import MyIM.client.view.component.JTKButton;
import MyIM.client.view.form.Dialog_AddFriend;
import MyIM.client.view.form.Dialog_AddGroup;
import MyIM.client.view.form.Dialog_Chat;
import MyIM.client.view.lnf.MetroStyle;
import MyIM.component.Friend;
import MyIM.component.Group;
import MyIM.utilities.Util;
import de.javasoft.swing.JYSearchField;
import de.javasoft.swing.JYTextField.PromptStrategy;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 *
 * @author Luan Nguyen Thanh <tklarryonline@gmail.com>
 */
public class ContactsView extends JPanel implements ActionListener, Observer {

//    private JYSearchField txtSearchContact;
    private JButton btnAddFriend, btnAddGroup;
    private JPanel pnContactsList;
    private JTree friendsList;
    private Engine engine;

    public ContactsView(Engine engine) {

        this.engine = engine;
        init();

    }

    private void init() {
        // Sets up components
        // Search field
//        txtSearchContact = new JYSearchField(30);
//        txtSearchContact.setPromptText("Find your friend");
//        txtSearchContact.setPromptStrategy(PromptStrategy.NO_TEXT);

        // Buttons
        btnAddFriend = new JTKButton("Add a Friend", Util.makeIcon(
                "add_user"));
        btnAddFriend.setPressedIcon(Util.makeIcon("add_user_hover"));
        btnAddFriend.setFont(MetroStyle.BUTTON_FONT);
        btnAddFriend.setIconTextGap(8);
        btnAddFriend.setFocusPainted(false);
        btnAddFriend.addActionListener(this);

        btnAddGroup = new JTKButton("Create a Group", Util.makeIcon(
                "add_group"));
        btnAddGroup.setPressedIcon(Util.makeIcon("add_group_hover"));
        btnAddGroup.setFont(MetroStyle.BUTTON_FONT);
        btnAddGroup.setIconTextGap(8);
        btnAddGroup.setFocusPainted(false);
        btnAddGroup.addActionListener(this);

        initLayout();
    }

    private void initLayout() {
        // Sets layout
        setLayout(new BorderLayout(3, 3));

        // Adds search field
//        add(txtSearchContact, BorderLayout.NORTH);

        // Adds contacts list
        pnContactsList = makeFriendsList();
        add(pnContactsList);

        // Adds buttons panel
        JPanel pnBtns = new JPanel(new GridBagLayout());
        GridBagConstraints cons = new GridBagConstraints();
        cons.fill = GridBagConstraints.HORIZONTAL;
        cons.weightx = 0.5;

        cons.gridx = 0;
        cons.gridy = 0;
        cons.insets = new Insets(3, 0, 3, 3);
        pnBtns.add(btnAddFriend, cons);

        cons.gridx++;
        cons.insets = new Insets(3, 3, 3, 0);
        pnBtns.add(btnAddGroup, cons);

        pnBtns.setBorder(BorderFactory.createEmptyBorder());
        add(pnBtns, BorderLayout.SOUTH);

        setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
    }

    private JPanel makeFriendsList() {
        JPanel mainPn = new JPanel(new BorderLayout());

        friendsList = createJTree();
        JScrollPane scrollPane = new JScrollPane(friendsList);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        mainPn.add(scrollPane);

        return mainPn;
    }

    public JTree getFriendsList() {
        return friendsList;
    }

    public void setFriendsList(JTree friendsList) {
        this.friendsList = friendsList;
        validate();
        repaint();
    }

    public void resetFriendsList() {
        pnContactsList.removeAll();
        pnContactsList.setLayout(new BorderLayout());
        friendsList = createJTree();
        JScrollPane scrollPane = new JScrollPane(friendsList);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        pnContactsList.add(scrollPane);
    }

    public JTree createJTree() {
        ImageIcon ava = Util.makeIcon("contact");
        // Creates JTree
        final JTree jTree = new JTree();
        jTree.setRootVisible(false);
        jTree.putClientProperty("JTree.lineStyle", "Horizontal");
        FriendListItem renderer = new FriendListItem();

        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
                "root node, should be invisible");
        DefaultTreeModel defaultTreeModel = new DefaultTreeModel(rootNode);

        jTree.setModel(defaultTreeModel);
        jTree.setCellRenderer(renderer);

        // Adds nodes to it
        DefaultMutableTreeNode parentNode;
        DefaultMutableTreeNode node;
        ArrayList<Group> groupList = engine.getClient().getFriendList();
        for (Group group : groupList) {
            System.out.println("Group Name: " + group.getGroupName());
            parentNode = (DefaultMutableTreeNode) defaultTreeModel.getRoot();
            node = new DefaultMutableTreeNode(group);
            addNodeToDefaultTreeModel(defaultTreeModel, parentNode, node);

            parentNode = node;
            ArrayList<Friend> friendInGroup = group.getFriends();
            for (Friend friend : friendInGroup) {
                node = new DefaultMutableTreeNode(friend);
                addNodeToDefaultTreeModel(defaultTreeModel, parentNode, node);
            }
        }
        
        expandAll(jTree);

        MouseListener ml = new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                int row = jTree.getRowForLocation(e.getX(), e.getY());
                TreePath path = jTree.getPathForLocation(e.getX(), e.getY());
                if (row != -1 && path != null) {
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
                    Object userObj = node.getUserObject();
                    if (userObj instanceof Friend) {
                        Friend friendObj = (Friend) userObj;
                        System.out.println("Object Friend " + friendObj.getDisplayName());
                        if (SwingUtilities.isLeftMouseButton(e)) {
                            if (e.getClickCount() == 2) {
                                startChat(friendObj);
                            }
                        } else if (SwingUtilities.isRightMouseButton(e)) {
                            FriendsPopupMenu fpop = new FriendsPopupMenu(ContactsView.this, engine, friendObj);
                            fpop.show(ContactsView.this, e.getX(), e.getY());

                        }
                    } else if (userObj instanceof Group) {
                        Group groupObj = (Group) userObj;
                        System.out.println("Object Group " + groupObj.getGroupName());
                        if (SwingUtilities.isRightMouseButton(e)) {
                            FriendsPopupMenu fpop = new FriendsPopupMenu(ContactsView.this, engine, groupObj);
                            fpop.show(ContactsView.this, e.getX(), e.getY());

                        }
                    }
                }
            }
        };

        jTree.addMouseListener(ml);

        return jTree;
    }

    public void expandAll(JTree tree) {
        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandRow(i);
        }
    }

    private void addNodeToDefaultTreeModel(DefaultTreeModel treeModel,
            DefaultMutableTreeNode parentNode, DefaultMutableTreeNode node) {

        treeModel.insertNodeInto(node, parentNode, parentNode.getChildCount());

        if (parentNode == treeModel.getRoot()) {
            treeModel.nodeStructureChanged((TreeNode) treeModel.getRoot());
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        if (cmd.equalsIgnoreCase(btnAddFriend.getActionCommand())) {
            addFriend();
        } else if (cmd.equalsIgnoreCase(btnAddGroup.getActionCommand())) {
            addGroup();
        }
    }

    private void addFriend() {
        Dialog_AddFriend dialogAddFriend = new Dialog_AddFriend(this, engine);

    }

    private void addGroup() {
        Dialog_AddGroup dialogAddGroup = new Dialog_AddGroup(this, engine);
    }

    private void startChat(Friend friend) {
        Client client = engine.getClient();
        engine.addNewDialogChat(friend.getUid(), new Dialog_Chat(engine, client.getDisplayName(), client.getAvatar(), friend));
    }

    @Override
    public void update(Observable o, Object arg) {
    }
}
